Add USD-denominated price chart#787
Conversation
Add reserve_usd_rate column to trade_history to store PLOT/USD at trade time. Both cron and webhook indexers now fetch and persist the rate. PriceChart gains a USD/PLOT toggle with dashed lines for approximate historical data. Includes tiered backfill script (exact via archive RPC, approximate fallback). Fixes #345 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
- Extract ONEINCH_SPOT_PRICE_AGGREGATOR to lib/contracts/constants.ts - Extract spotPriceAbi to lib/contracts/abi.ts - Add CHECK constraint on rate_source column - Document USDC 6-decimal assumption Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
The overall direction is sound, but the current implementation still writes materially incorrect USD history in a couple of paths. I would not ship this as-is because it can present stale or miscomputed USD prices as if they were historical truth.
Findings
-
[high] The approximate backfill path does not implement the strategy described in the PR.
getCurrentPlotUsd()fetches a single current PLOT/USD rate and reuses that same value for every historical block, so rows markedbackfill_approxignore historical HUNT/USD entirely.- File:
scripts/backfill-usd-rates.ts:91 - Suggestion: fetch historical HUNT/USD for each trade date/block in the approximate path, or explicitly rename/reframe this source as a current-rate extrapolation instead of a historical approximation.
- File:
-
[medium] The cron indexer fetches one current PLOT/USD rate per 200-block scan and stamps it onto every trade in that batch as
live. If the cursor is catching up after downtime, those rows can be several minutes or more away from the actual trade time while still being labeled as exact live data.- File:
src/app/api/cron/trade-history/route.ts:90 - Suggestion: fetch/cache the reserve USD rate per unique block (or per event timestamp bucket), or mark batch-stamped rows differently so they are not indistinguishable from exact-at-trade-time data.
- File:
-
[medium] In USD mode the chart filters out rows with
reserve_usd_rate = null, then uses the last remaining USD point aslatest. If the newest trades are missing a USD rate, the component will silently hide those rows and label an older point as the latest price.- File:
src/components/PriceChart.tsx:132 - Suggestion: do not collapse missing-rate rows out of the timeline when presenting a latest USD price. Either show a visible gap/stale state, or only default to USD when the newest displayed trade has a USD rate.
- File:
Decision
Requesting changes because the current data pipeline can write or display inaccurate USD history without clearly communicating that loss of precision.
…test - Backfill script now reads historical HUNT/USD per-block instead of using a single current PLOT/USD for all rows - Cron indexer marks trades as 'backfill_approx' during catch-up scans (>200 blocks behind head) instead of falsely labeling as 'live' - PriceChart labels last USD point as "last USD" (not "latest") when newer trades exist without USD data Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
Two of my prior concerns look addressed, but one correctness issue remains in the cron path. The current catch-up detection still allows materially stale USD rates to be labeled as live for part of the final backlog batch.
Findings
- [medium]
isCatchUpis derived fromcurrentBlock - toBlock, but the batch writes one sharedreserve_usd_rate/rate_sourceacross the whole[fromBlock, toBlock]window. In the final catch-up batch,toBlockcan be within 200 blocks of head whilefromBlockis still nearly 400 blocks behind, so older trades in that same batch are stamped asliveeven though they are not near-head.- File:
src/app/api/cron/trade-history/route.ts:94 - Suggestion: base the label on the oldest block in the batch (for example
currentBlock - fromBlock), or compute/cache the reserve USD rate per event block / smaller bucket so that only truly near-head trades getlive.
- File:
Decision
Keeping this in request-changes until the cron labeling semantics match the precision of the data being written.
… check Use fromBlock (oldest block in batch) instead of toBlock to determine catch-up status. Prevents the final catch-up batch from mislabeling older trades as 'live' when toBlock happens to be near head. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Summary
The remaining cron-labeling issue is fixed. Using fromBlock for the catch-up check is the conservative behavior I was asking for, and I do not have further correctness blockers on this PR.
Findings
- None.
Decision
Approved based on the current implementation and the issues addressed in the follow-up revisions.
Summary
reserve_usd_rateandrate_sourcecolumns totrade_historytable (migration 00031)lib/reserve-usd-rate.tsPriceChart.tsxgains a USD/PLOT segmented toggle (defaults to USD when data available)scripts/backfill-usd-rates.ts) with tiered strategy: exact historical reads via archive-capable RPCs, falling back to approximate current-rate extrapolationDesign Decisions
priceForNextMint(PLOT_TOKEN)in HUNT × HUNT/USD via 1inch spot oracleeth_call; approximate otherwise. Rows tagged withrate_source(live,backfill_exact,backfill_approx) for future re-backfillreserve_usd_rate= NULL, chart falls back to reserve-only displayApproximate Data Disclosure
Per T2a review requirement: approximate USD data points are visually distinguished with dashed line segments and reduced opacity, plus a footnote when the chart contains any approximate data.
Test Plan
reserve_usd_rateandrate_source='live'on new tradesreserve_usd_raterows (should fall back to reserve-only)npx tsx scripts/backfill-usd-rates.tsto backfill existing tradesbackfill_approxdata pointsFixes #345
🤖 Generated with Claude Code